#ifndef PARSER_H
#define PARSER_H
#include <stack>
#include "scanner.h"
#include "lex.h"
#include "prog.h"
using namespace std;

class parser
{
    lex curr_lex, prev_lex;
    int c_val;
    scanner m_scan;

    stack<value_t> st_run;
    stack<lex_type_t> st_lex;
    stack<bool> st_expr_was_const;
    stack<int> st_loops_entryp;

    stack<lex> gl_buff;
    prog m_prog;


    bool expr_was_const;



    void gl() {
        if (gl_buff.size()) {
            curr_lex = gl_buff.top();
            gl_buff.pop();
        } else {
            prev_lex = curr_lex;
            curr_lex = m_scan.get_lex();
            if (prev_lex.get_type() != LEX_IDENT
                    && prev_lex.get_type() != LEX_NUM
                    && prev_lex.get_type() != LEX_STRING
                    && prev_lex.get_type() != LEX_BOOL
                    && prev_lex.get_type() != LEX_RPAREN) {

                if (curr_lex.get_type() == LEX_PLUS) {
                    curr_lex.set_type(LEX_UNARY_PLUS);
                }

                if (curr_lex.get_type() == LEX_MINUS) {
                    curr_lex.set_type(LEX_UNARY_MINUS);
                }
            }
        }

    }
    void ungl(const lex &p) {
        gl_buff.push(p);
    }

    void check_id(bool push = true); //
    void check_bool();
    void check_op();
    void check_not();
    void eq_type();
    bool is_type();
    bool is_cmp(lex_type_t);
    bool is_assign(lex_type_t op);
    void run();
    void assign_run(lex& p);
    void cmp_run(lex& p);

    void P();
    void D1();
    //void D();
    void B(); //B();
    void S(bool disable_complex = false);
    void E1();
    void E2();
    void E3();
    void E();
    void empty_E();
    void T();
    void F();
    void M();
public:
    parser(const string &fname);
    void analyze() {
        gl();
        P();
        cout << "EVERYTHING IS OK!" << endl;
        for (int i = 0; i < m_prog.size(); i++) {
            cout <<  i << " "<< m_scan.print_lex(m_prog[i]) << endl;
        }
        cout << "RESULTS" << endl;
        run();
    }
};

#endif // PARSER_H
